using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player_States : IState
{
    protected Player_FSM stateMachine;
    protected Animator animator;

    protected float curretnSpeed;

    float stateStartTime;
    protected float StateDuration => Time.time - stateStartTime;
    protected bool IsStateFinished => StateDuration >= animator.GetCurrentAnimatorStateInfo(0).length;

    public virtual void Enter()
    {
        stateStartTime = Time.time;
    }

    public virtual void Exit()
    {
        
    }

    public virtual void LogicUpdate()
    {

    }

    public virtual void PhySicsUpdate()
    {
        
    }
}
public class PlayerState_Idle : Player_States
{
    public PlayerState_Idle(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        curretnSpeed = stateMachine.MoveSpeed;
        animator.Play("Idle");
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if(stateMachine.HasJumpBuffer || stateMachine.IsJump)
        {
            stateMachine.StateSwitch(PlayerState.Jump);
        }
        if (stateMachine.IsMove)
        {
            stateMachine.StateSwitch(PlayerState.Walk);
        }
        curretnSpeed = Mathf.MoveTowards(curretnSpeed,0,stateMachine.GetDeceleration()* Time.deltaTime);
    }
    public override void PhySicsUpdate()
    {
        base.PhySicsUpdate();
        stateMachine.SetVelocityX(curretnSpeed);
    }
    public override void Exit()
    {
        base.Exit();
    }
}
public class PlayerState_Walk : Player_States
{
    public PlayerState_Walk(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("Walk");
        curretnSpeed = stateMachine.MoveSpeed;
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (stateMachine.HasJumpBuffer || stateMachine.IsJump)
        {
            stateMachine.StateSwitch(PlayerState.Jump);
        }
        if (!stateMachine.IsMove)
        {
            stateMachine.StateSwitch(PlayerState.Idle);
        }
        curretnSpeed = Mathf.MoveTowards(curretnSpeed, stateMachine.GetRunSpeed() * stateMachine.MoveX, stateMachine.GetAcceleration() * Time.deltaTime);
    }
    public override void PhySicsUpdate()
    {
        base.PhySicsUpdate();
        stateMachine.Flip();
        stateMachine.SetVelocityX(curretnSpeed);
    }
    public override void Exit()
    {
        base.Exit();
    }
}
public class PlayerState_Jump : Player_States
{
    public PlayerState_Jump(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        stateMachine.SetVelocityY(stateMachine.GetJumpForce());
        animator.Play("Jump");
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (stateMachine.IsFall)
        {
            stateMachine.StateSwitch(PlayerState.Fall);
        }
    }
    public override void PhySicsUpdate()
    {
        base.PhySicsUpdate();
        stateMachine.FlipInAir();
    }
    public override void Exit()
    {
        base.Exit();
    }
}
public class PlayerState_Fall : Player_States
{
    public PlayerState_Fall(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("Fall");
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (stateMachine.IsJump)
        {
            stateMachine.SetJumpBuffer();
        }
        if (stateMachine.IsGround)
        {
            stateMachine.StateSwitch(PlayerState.Land);
        }
    }
    public override void PhySicsUpdate()
    {
        base.PhySicsUpdate();
        stateMachine.FlipInAir();
    }
    public override void Exit()
    {
        base.Exit();
    }
}
public class PlayerState_Land : Player_States
{
    public PlayerState_Land(Player_FSM stateMachine, Animator animator)
    {
        this.stateMachine = stateMachine;
        this.animator = animator;
    }
    public override void Enter()
    {
        base.Enter();
        animator.Play("Land");
        stateMachine.SetVelocityX(0);
    }
    public override void LogicUpdate()
    {
        base.LogicUpdate();
        if (stateMachine.HasJumpBuffer || stateMachine.IsJump)
        {
            stateMachine.StateSwitch(PlayerState.Jump);
        }
        if (IsStateFinished)
        {
            stateMachine.StateSwitch(PlayerState.Idle);
        }
    }
    public override void PhySicsUpdate()
    {
        base.PhySicsUpdate();
    }
    public override void Exit()
    {
        base.Exit();
    }
}